package com.lf.sys.util;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.security.Security;
import java.util.Date;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.apache.commons.lang3.StringUtils;

public class MailConnect {
	private Properties properties;
	private Session session;
	private Store store;
	private Folder[] folders;
	private MailBean mailBean;
	private int state = 0;
	private String errorMsg;

	public MailConnect(MailBean mailBean) {
		this.setMailBean(mailBean);
	}

	/**
	 * 检查是否可用
	 */
	public void checkProperties() {
		this.init();
		try {
			Folder temp = this.store.getFolder("INBOX");
			temp.open(Folder.READ_ONLY);
			temp.close(false);
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			this.state = 3;
			this.errorMsg = e.getMessage();
		}
		this.stop();
	}

	/**
	 * 初始化，状态写在state中
	 */
	public void init() {
		if (this.mailBean == null || this.mailBean.isNull()) {
			this.state = 1;
			this.errorMsg = "MAILBEAN_EMPTY";
			return;
		}
		// 设置properties开始
		this.properties = System.getProperties();
		if (StringUtils.isNotBlank(this.mailBean.getHostProp()) && StringUtils.isNotBlank(this.mailBean.getHost())) {
			this.properties.setProperty(this.mailBean.getHostProp(), this.mailBean.getHost());
		}
		if (StringUtils.isNotBlank(this.mailBean.getPortProp()) && StringUtils.isNotBlank(this.mailBean.getPort())) {
			this.properties.setProperty(this.mailBean.getPortProp(), this.mailBean.getPort());
		}
		if (StringUtils.isNotBlank(this.mailBean.getProtocolProp())
				&& StringUtils.isNotBlank(this.mailBean.getProtocol())) {
			this.properties.setProperty(this.mailBean.getProtocolProp(), this.mailBean.getProtocol());
		}

		if (this.mailBean.isSSL()) {
			if (StringUtils.isNotBlank(this.mailBean.getAuthProp())
					&& StringUtils.isNotBlank(this.mailBean.getAuth())) {
				this.properties.setProperty(this.mailBean.getAuthProp(), this.mailBean.getAuth());
			}
			if (StringUtils.isNotBlank(this.mailBean.getSocketFactoryClassProp())
					&& StringUtils.isNotBlank(this.mailBean.getSocketFactoryClass())) {
				this.properties.setProperty(this.mailBean.getSocketFactoryClassProp(),
						this.mailBean.getSocketFactoryClass());
			}
			if (StringUtils.isNotBlank(this.mailBean.getSocketFactoryFallbackProp())
					&& StringUtils.isNotBlank(this.mailBean.getSocketFactoryFallback())) {
				this.properties.setProperty(this.mailBean.getSocketFactoryFallbackProp(),
						this.mailBean.getSocketFactoryFallback());
			}
			if (StringUtils.isNotBlank(this.mailBean.getSocketFactoryPortProp())
					&& StringUtils.isNotBlank(this.mailBean.getSocketFactoryPort())) {
				this.properties.setProperty(this.mailBean.getSocketFactoryPortProp(),
						this.mailBean.getSocketFactoryPort());
			}

		}
		if (this.mailBean.isSSL()) {
			Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
		}
		// 设置properties结束
		// 获取连接
		this.session = Session.getDefaultInstance(this.properties);
		this.session.setDebug(false);
		// 获取Store对象
		try {
			this.store = this.session.getStore(this.mailBean.getProtocol());
			this.store.connect(this.mailBean.getAccount(), this.mailBean.getPassword());
			this.folders = this.store.getDefaultFolder().list();
		} catch (NoSuchProviderException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			this.state = 2;
			this.errorMsg = e.getMessage();
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			this.state = 3;
			this.errorMsg = e.getMessage();
		}
	}

	/**
	 * 根据名称获取文件夹
	 * 
	 * @param name
	 * @return
	 */
	public Folder getFolderByName(String[] name) {
		Folder folder = null;
		boolean flag = true;
		try {
			for (int i = 0; i < name.length; i++) {
				folder = this.store.getFolder(name[i]);
				if (folder.exists()) {
					flag = false;
					break;
				}
			}
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			this.state = 3;
			this.errorMsg = e.getMessage();
		}
		if (flag) {
			folder = null;
		}
		return folder;
	}

	/**
	 * 获取收件箱
	 * 
	 * @return
	 */
	public Folder getINFolder() {
		String[] temp = { "INBOX" };
		return this.getFolderByName(temp);
	}

	/**
	 * 获取发件箱
	 * 
	 * @return
	 */
	public Folder getSentFolder() {
		String[] temp = { "已发送", "Sent Messages" };
		return this.getFolderByName(temp);
	}

	/**
	 * 获取删除邮件
	 * 
	 * @return
	 */
	public Folder getDeletedFolder() {
		String[] temp = { "已删除邮件", "Deleted Messages", "草稿箱" };
		return this.getFolderByName(temp);
	}

	/**
	 * 获取垃圾邮件
	 * 
	 * @return
	 */
	public Folder getJunkFolder() {
		String[] temp = { "垃圾邮件", "Junk" };
		return this.getFolderByName(temp);
	}

	/**
	 * 获取草稿箱
	 * 
	 * @return
	 */
	public Folder getDraftsFolder() {
		String[] temp = { "草稿", "Drafts", "已删除" };
		return this.getFolderByName(temp);
	}

	public enum FolderType {
		// "收件箱 ", "草稿箱 ", "发件箱 ","已删除","垃圾箱 "
		INFolder, DraftsFolder, SentFolder, DeletedFolder, JunkFolder
	}

	public boolean setMessageFlag(FolderType folderType, String messageId, String sendDate, Flag flag, boolean state) {
		Folder f = null;
		switch (folderType) {
		case INFolder:
			f = this.getINFolder();
			break;
		case DraftsFolder:
			f = this.getDraftsFolder();
			break;
		case SentFolder:
			f = this.getSentFolder();
			break;
		case DeletedFolder:
			f = this.getDeletedFolder();
			break;
		case JunkFolder:
			f = this.getJunkFolder();
			break;
		}
		if (f == null) {
			return false;
		}
		if (!f.isOpen()) {
			try {
				f.open(Folder.READ_WRITE);
			} catch (MessagingException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
				this.state = 1;
				this.errorMsg = e1.getMessage();
				return false;
			}
		}
		boolean temp = true;
		try {
			Message[] msg = f.getMessages();
			for (int i = 0; i < msg.length; i++) {
				MimeMessage mimeMessage = (MimeMessage) msg[i];
				if (mimeMessage.getMessageID().equalsIgnoreCase(messageId)
						&& sendDate.trim().equals(String.valueOf(mimeMessage.getSentDate().getTime()))) {
					msg[i].setFlag(flag, state);
					break;
				}
			}
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			this.errorMsg = e.getMessage();
			temp = false;
			e.printStackTrace();
		}
		return temp;
	}

	/**
	 * 
	 * @param folder
	 * @param id
	 * @return
	 */
	public boolean deleteMessage(FolderType folderType, String messageId, String sendDate) {
		return this.setMessageFlag(folderType, messageId, sendDate, Flags.Flag.DELETED, true);
	}

	/**
	 * 
	 * @param folder
	 * @param id
	 * @return
	 */
	public boolean readMessage(FolderType folderType, String messageId, String sendDate) {
		return this.setMessageFlag(folderType, messageId, sendDate, Flags.Flag.SEEN, true);
	}

	/**
	 * 
	 * @param folder
	 * @param id
	 * @return
	 */
	public boolean unReadMessage(FolderType folderType, String messageId, String sendDate) {
		return this.setMessageFlag(folderType, messageId, sendDate, Flags.Flag.SEEN, false);
	}

	/**
	 * 用完后记得释放资源
	 */
	public void stop() {
		try {
			this.store.close();
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for (int i = 0; i < this.folders.length; i++) {
			if (this.folders[i].isOpen()) {
				try {
					this.folders[i].close(false);
				} catch (MessagingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					this.state = 3;
					this.errorMsg = e.getMessage();
				}
			}
		}
	}

	public Properties getProperties() {
		return properties;
	}

	public void setProperties(Properties properties) {
		this.properties = properties;
	}

	public Session getSession() {
		return session;
	}

	public void setSession(Session session) {
		this.session = session;
	}

	public Store getStore() {
		return store;
	}

	public void setStore(Store store) {
		this.store = store;
	}

	public Folder[] getFolders() {
		return folders;
	}

	public void setFolders(Folder[] folders) {
		this.folders = folders;
	}

	public MailBean getMailBean() {
		return mailBean;
	}

	public void setMailBean(MailBean mailBean) {
		this.mailBean = mailBean;
	}

	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
	}

	public String getErrorMsg() {
		return errorMsg;
	}

	public void setErrorMsg(String errorMsg) {
		this.errorMsg = errorMsg;
	}
}
